﻿using System;

namespace DelegateStudy
{

    public delegate void MyFun();//无参无返回值函数委托
    public delegate void MyFun2(int a);
    public delegate void MyFun3<T>(T a);//带一个参数无返回值的函数委托
    //函数委托是不允许发生重载的（不能有两个相同的委托名）
    class Program
    {
        static void Main1(string[] args)
        {
            //Console.WriteLine("Hello World!");
            MyFun myFun = new MyFun(Fun);
            MyFun2 myFun11 = new MyFun2(FunA);
            MyFun myFun22 = Fun;
            MyFun3<String> myFun33 = FunB;
            //以上是函数委托的实例化，可以使用new 的原因因为委托本质上是一种类
            myFun.Invoke();
            myFun11.Invoke(666);
            myFun22();
            myFun33("hhh");
            Console.WriteLine("===============");
            MyFun my1 = null;
            my1 += Fun;
            my1 += Fun1;
            my1 -= Fun;
            my1 -= Fun1;
            my1 -= Fun1;
            if(!(my1==null))
            my1();
            Console.WriteLine("===============");
            //使用系统已经定义好的函数委托
            //Acthion是系统自定义的无返回值函数委托(可最大支持16个参数)
            Console.WriteLine("Acthion委托使用");
            Action action = Fun1;
            Action<int> action1 = FunA;
            Action<int, String> action3 = FunC;
            action.Invoke();
            action1.Invoke(66);
            action3.Invoke(55, "");
            Console.WriteLine("===============");

            //Func是系统定义好的委托，当泛型只有一个时代表的是无参有返回值的函数委托，且返回值就是该泛型类型
            //如果有多个泛型那么除了泛型列表的最后一个泛型类型是函数返回值类型之外，其他的都是函数的参数类型
            Console.WriteLine("Func委托使用");
            Func<int> func1 = f1;//无参有返回值(返回值为int)
            Func<int, bool, String> func2 = f2;//


            Console.WriteLine(func1.Invoke());

            Console.WriteLine(func2.Invoke(44, true));

        }

        static void Fun() {
            Console.WriteLine("Myfun:  Fun()");
        }

        static void Fun1()
        {
            Console.WriteLine("Myfun:  Fun1()");
        }

        static void FunA(int a)
        {
            Console.WriteLine("Myfun1:  FunA() a="+a);
        }

        static void FunB(String str)
        {
            Console.WriteLine("Myfun1:  FunA()"+str);
        }

        static void FunC(int a, String str) {
            Console.WriteLine("FunC");
        }
        //===
        static int f1() { return 11111; }
        static String f2(int a, bool flag) { return "666"; }
    }
}
